﻿using DH.Core;
using DH.Core.Exceptions;
using DH.Core.Helper;
using DH.Core.UI.ViewModel;
using DH.Web.Extensions;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;

namespace DH.Web.Controllers
{

  public abstract  class ControllerBase:Controller
    {
        private readonly IExceptionMapper _exceptionMapper;

        protected ControllerBase(IServiceCollection service)
        {
            _exceptionMapper = service.BuildServiceProvider().GetService<IExceptionMapper>();
        }
        protected virtual IActionResult BadRequestResult(ModelStateDictionary modelState)
        {
            // ToDo : does this have to be logged ?
            //return new BadRequestObjectResult(modelState);
            var errorMessages = modelState.AllModelStateErrors();
            var message = string.Join(",", errorMessages.Select(x => x.ErrorMessage));
            return Content(new AjaxResult { Status = ResultTypeEnum.error.ToString(), Msg = message }.ToJson());
        }
        protected virtual IActionResult BadRequestResult(ValidationException validationEx)
        {
            // ToDo : does this have to be logged ?
            var modelState = new ModelStateDictionary();
            foreach (var messages in validationEx.Messages.Values)
            {
                foreach (var message in messages)
                {
                    modelState.AddModelError(String.Empty, message);
                }
            }
            return BadRequestResult(modelState);

        }


        protected virtual IActionResult BadRequestResult(IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> validationResults)
        {
            // ToDo : does this have to be logged ?
            var modelState = new ModelStateDictionary();
            foreach (var validationResult in validationResults)
            {
                modelState.AddModelError(String.Empty, validationResult.ErrorMessage);
            }
            return BadRequestResult(modelState);

        }

        protected virtual IActionResult CreatedAtRouteResult(string routeName, object routeValues, object value)
        {
            return new CreatedAtRouteResult(routeName, routeValues, value);
        }

        protected virtual IActionResult InternalServerError(Exception ex, string message, params object[] args)
        {
            if (ex == null)
            {
               
                var error = new ServerErrorException(string.Format(message, args));
                return Content(new AjaxResult { Status = ResultTypeEnum.error.ToString(), Msg = _exceptionMapper.Resolve(error).ToString() }.ToJson());
            }
            else
            {
                var errorMessage = String.Format(message, args);               
                var error = new ServerErrorException(string.Format("{0} : {1}", errorMessage, ex.Message));
                return Content(new AjaxResult { Status = ResultTypeEnum.error.ToString(), Msg = errorMessage }.ToJson());
            }
        }

        protected virtual IActionResult OkResult()
        {
            return new StatusCodeResult(200);
        }

        protected virtual IActionResult OkResult(object value)
        {
            return new ObjectResult(value) { StatusCode = 200 };
        }

        protected virtual IActionResult NotFoundResult(string message, params object[] args)
        {
            
            var error = new NotFoundException(string.Format(message, args));
            return new ObjectResult(_exceptionMapper.Resolve(error)) { StatusCode = 404 };
        }


        /// <summary>
        /// 返回成功消息
        /// </summary>
        /// <param name="message">消息</param>
        /// <returns></returns>
        protected virtual ActionResult Success(string message)
        {
            return Content(new AjaxResult { Status = ResultTypeEnum.success.ToString(), Msg = message }.ToJson());
        }
        /// <summary>
        /// 返回成功消息
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        protected virtual ActionResult Success(string message, object data)
        {
            return Content(new AjaxResult { Status = ResultTypeEnum.success.ToString(), Msg = message, Data = data }.ToJson());
        }
        /// <summary>
        /// 返回失败消息
        /// </summary>
        /// <param name="message">消息</param>
        /// <returns></returns>
        protected virtual ActionResult Error(string message)
        {
            return Content(new AjaxResult { Status = ResultTypeEnum.error.ToString(), Msg = message }.ToJson());
        }

        protected virtual ActionResult SuccessMessage(string message="")
        {
            return SuccessMessage(null,message);
        }
        protected virtual ActionResult SuccessMessage(object data, string message = "") {

            return Content(new AjaxResult { Status = ResultStatusEnum.OK, Msg = message,Data=data }.ToJson());
        }
        protected virtual ActionResult ErrorMessage(string message="")
        {
            return Content(new AjaxResult { Status = ResultStatusEnum.Failed, Msg = message }.ToJson());
        }

        UserSession _session;
        public UserSession CurrentUser
        {
            get
            {
                //_session 存在返回
                if (_session != null)
                {
                    return _session;
                }
                //授权失败
                if (HttpContext.User.Identity.IsAuthenticated == false)
                {
                    return null;
                }

                UserSession session = UserSession.Parse(this.HttpContext.User);
                this._session = session;
                return session;

            }
            set
            {
                UserSession session = value;

                var scheme = CookieAuthenticationDefaults.AuthenticationScheme;
                if (session == null)
                {
                    //退出登陆
                    this.HttpContext.SignOutAsync(scheme);
                    return;
                }

                var cliams = session.ToClaims();

                var identity = new ClaimsIdentity(cliams, scheme);
                var claimsPrincipal = new ClaimsPrincipal(identity);
                this.HttpContext.SignInAsync(scheme, claimsPrincipal, new AuthenticationProperties
                {
                    ExpiresUtc = DateTime.UtcNow.AddMinutes(60),
                    IsPersistent = false,
                    AllowRefresh = false
                });

                _session = session;
            }
        }

                
    }
}
